﻿#include <arpa/inet.h>
#include <netinet/in.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <sys/socket.h>
#include <unistd.h>

int main() {
    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();

    const SSL_METHOD *method = TLS_server_method();
    SSL_CTX          *ctx    = SSL_CTX_new(method);
    if (ctx == NULL) {
        ERR_print_errors_fp(stderr);
        return 1;
    }

    // 加载证书和私钥
    if (SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        return 1;
    }
    if (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        return 1;
    }

    int                server_fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in address;
    address.sin_family      = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port        = htons(8443);

    bind(server_fd, (struct sockaddr *)&address, sizeof(address));
    listen(server_fd, 3);

    while (true) {
        int  client_fd = accept(server_fd, (struct sockaddr *)NULL, NULL);
        SSL *ssl       = SSL_new(ctx);
        SSL_set_fd(ssl, client_fd);

        if (SSL_accept(ssl) <= 0) {
            ERR_print_errors_fp(stderr);
        } else {
            char buffer[⁠⁣ ⁠⁣< font sizeToken = common_footnote_text_style__font_size backgroundColorToken = common_gray6_color colorTokenV2 = common_level3_base_color > 1024 < / font > ];
            SSL_read(ssl, buffer, sizeof(buffer));
            printf("Received: %s\n", buffer);

            const char *msg = "Hello, Client!";
            SSL_write(ssl, msg, strlen(msg));
        }

        SSL_free(ssl);
        close(client_fd);
    }

    SSL_CTX_free(ctx);
    EVP_cleanup();
    return 0;
}
